package modele.case_;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import modele.Dessinable;
import modele.Drapeau;
import modele.Plateau;
import modele.ex.ErreurFormatPlateau;
import modele.pion.Pion;
import outils.gestionnairefichier.GestionnaireImage;

/**
 * Représente une des cases du plateau
 *
 * @author gervaila
 */
public abstract class Case implements Dessinable {

	/**
	 *
	 * @param c le code de la case
	 * @param x l'abscisse de la case
	 * @param y l'ordonnée de la case
	 * @return la case Correspondant au code 'c' qui contient les coordonnées
	 * (x,y)
	 * @throws ErreurFormatPlateau
	 */
	public static Case getCaseCode(char c, int x, int y) throws ErreurFormatPlateau {
		switch (c) {
			case Code.EAU:
				return new CaseEau(x, y);
			case Code.TERRE:
				return new CaseTerre(x, y);
			case Code.MONTAGNE:
				return new CaseMontagne(x, y);
			case Code.VIDE:
				return new CaseVide(x, y);
			case Code.DRAPEAU1:
				return new CaseDrapeau(x, y, 1);
			case Code.DRAPEAU2:
				return new CaseDrapeau(x, y, 2);
			case Code.TROU1:
				return new CaseTrouDrapeau(x, y, 1);
			case Code.TROU2:
				return new CaseTrouDrapeau(x, y, 2);
			default:
				throw new ErreurFormatPlateau();
		}
	}

	/**
	 * Definition de constantes pour le format de fichier représentant les
	 * plateaux
	 */
	public abstract class Code {

		/**
		 * symbole de la case TERRE
		 */
		public static final char TERRE = '_';
		/**
		 * symbole de la case EAU
		 */
		public static final char EAU = 'e';
		/**
		 * symbole de la case MONTAGNE
		 */
		public static final char MONTAGNE = 'm';
		/**
		 * symbole de la case VIDE
		 */
		public static final char VIDE = ' ';
		/**
		 * symbole de la case TERRE contenant le drapeau du joueur 1
		 */
		public static final char DRAPEAU1 = '1';
		/**
		 * symbole de la case TERRE contenant le drapeau du joueur 2
		 */
		public static final char DRAPEAU2 = '2';
		/**
		 * symbole pour la case accueillant le drapeau du joueur 1
		 */
		public static final char TROU1 = 'R';
		/**
		 * symbole pour la case accueillant le drapeau du joueur 2
		 */
		public static final char TROU2 = 'V';
	}
	/**
	 * coordonnées de la case
	 */
	protected Point coord;
	/**
	 * le drapeau sur la case
	 */
	protected Drapeau drapeau;
	private Pion pion;
	/**
	 * L'adresse de l'image représentant la case
	 */
	protected String image;

	/**
	 * Crée la case en position x, y avec l'image à l'adresse 'image'
	 *
	 * @param x l'abscisse de la case
	 * @param y l'ordonnée de la case
	 * @param image l'adresse de l'image de la case
	 */
	public Case(int x, int y, String image) {
		this.coord = new Point(x, y);
		this.pion = null;
		this.image = image;
	}

	/**
	 * Affecte un pion à la case
	 *
	 * @param pion le Pion à affecter à cette case
	 */
	public void setPion(Pion pion) {
		this.pion = pion;
		if (pion != null) {
			pion.setCase(this);
			if (drapeau != null) {
				pion.setDrapeau(drapeau);
				drapeau = null;
			}
		}
	}

	/**
	 *
	 * @return le pion présent sur cette case
	 */
	public Pion getPion() {
		return pion;
	}

	/**
	 *
	 * @return le drapeau sur cette case
	 */
	public Drapeau getDrapeau() {
		return drapeau;
	}

	/**
	 * Affecte un drapeau à la case
	 *
	 * @param drapeau le drapeau à affecter
	 */
	public void setDrapeau(Drapeau drapeau) {
		this.drapeau = drapeau;
		if (drapeau != null) {
			drapeau.setCase(this);
			drapeau.setPion(null);
		}
	}

	/**
	 *
	 * @return les coordonnées de la case
	 */
	public Point getCoord() {
		return coord;
	}

	/**
	 *
	 * @return l'abscisse de la case
	 */
	public int getX() {
		return coord.x;
	}

	/**
	 *
	 * @return l'ordonnée de la case
	 */
	public int getY() {
		return coord.y;
	}

	/**
	 *
	 * @return l'adresse de l'image de la case
	 */
	public String getImage() {
		return image;
	}

	@Override
	public void dessiner(Graphics2D gr, vue.Camera camera) {
		BufferedImage img = GestionnaireImage.getInstance().get(image);
		gr.drawImage(img, coord.x * Plateau.TAILLE_CASE, coord.y * Plateau.TAILLE_CASE, null);
	}

	/**
	 * Copie la case sans son pion éventuel
	 *
	 * @return la case copiée
	 */
	public abstract Case copier();
}
